<?php
/**
 * Easthv Zend Framework Project
 *
 * LICENSE:
 *
 * @category   Zend
 * @package    Zend_Easthv
 * @copyright  Copyright (c) 2009-2010 Easthv Team @ East Hui Van Business Consulting Co., Ltd.(http://www.easthv.com)
 * @license    http://framework.zend.com/license/   BSD License
 * @version    1.0
 * @link       http://www.easthv.com
 * @since      1.0
*/

/**
 * DateTime class
 *
 * @category   Zend
 * @package    Zend_Easthv
 * @copyright  Copyright (c) 2009-2010 Easthv Team @ East Hui Van Business Consulting Co., Ltd.(http://www.easthv.com)
 * @license    http://framework.zend.com/license/   BSD License
 * @version    1.0
 * @link       http://www.easthv.com
 * @since      1.0
 * @deprecated
 */
class Zend_Easthv_Date
{
    /**
     * Parse any datetime strig to UTC datetime with database format
     * For saving data to DB
     *
     * @access public
     * @param string $time  datetime string
     * @param int $timezone  timezone int
     *
     * @return string datetime format
     */
    public static function toUTC($time, $timezone = 0)
    {
        date_default_timezone_set('UTC');
        $time = strtotime($time);
        $time = $time - $timezone * 3600;
        return gmdate('Y-m-d H:i:s', $time);
    }
    
    /**
     * Get current datetime
     *
     * @access public
     * @param int $timezone  timezone int
     *
     * @return string datetime format
     */
    public static function getNow($timezone = 0, $format = 'Y-m-d H:i:s')
    {
        date_default_timezone_set('UTC');
        return gmdate($format, mktime() + $timezone * 3600);
    }

    /**
     * Get current date
     *
     * @access public
     * @param int $timezone  timezone int
     *
     * @return string date format
     */
    public static function getNowDate($timezone = 0, $format = 'Y-m-d')
    {
        date_default_timezone_set('UTC');
        return gmdate($format, mktime() + $timezone * 3600);
    }
    
    /**
     * Get diff days between 2 dates
     *
     * @access public
     * @param string $startDate  date string
     * @param string $endDate  date string
     *
     * @return int days
     */
    public static function getDiffDays($startDate, $endDate)
    {
        if ($startDate == $endDate) {
            return 0;
        }

        return ceil ((strtotime($endDate) - strtotime($startDate)) / 3600 / 24);
    }
    
    /**
     * Get a certain date in past by input seconds
     *
     * @access public
     * @param int $seconds  seconds int
     * @param string $startDate  datetime string
     * @param string $format date format
     *
     * @return string date format
     */
    public static function getBefore($seconds = 0, $startDay = null, $format = 'Y-m-d', $timezone = 0)
    {
		date_default_timezone_set('UTC');
        if (!$startDay) {
            return gmdate($format, mktime() - $seconds + $timezone * 3600);
        } else {
			return gmdate($format, strtotime($startDay) - $seconds);
		}
    }
    
    /**
     * Get a certain date in future by input seconds
     *
     * @access public
     * @param int $seconds  seconds int
     * @param string $startDate  datetime string
     * @param string $format date format
     *
     * @return string date format
     */
    public static function getFuture($seconds = 0, $startDay = null, $format = 'Y-m-d', $timezone = 0)
    {
        date_default_timezone_set('UTC');
        if (!$startDay) {
            return gmdate($format, mktime() + $seconds + $timezone * 3600);
        } else {
            return gmdate($format, strtotime($startDay) + $seconds);
        }    
    }
    
    /**
     * Change a datetime into another format
     * If no date input, will return current time
     *
     * @access public
     * @param string $format format string
     * @param string $date  date string
     * @param int $timezone  timezone int
     *
     * @return string date format
     */
    public static function changeDateByFormat($format = 'Y-m-d', $date = null, $timezone = 0)
    {
        date_default_timezone_set('UTC');
        if (!$date) {
            return gmdate($format, mktime() + $timezone * 3600);
        } else {
            return gmdate($format, strtotime($date) + $timezone * 3600);
        }    
    }
	
	public function getWeekInfo($day = null, $format = 'Y-m-d')
	{
	    date_default_timezone_set('UTC');
		
		if (!$day) {
            $day = gmdate($format, mktime());
        }  	
	
		$weekDay = date('N',strtotime($day));
		
		if ($weekDay == 1) {
			$res['Monday'] = $day;
			$res['Sunday'] = self::getFuture(7*24*3600, $day, $format);
		} else if ($weekDay == 7) {
			$res['Monday'] = self::getBefore(7*24*3600, $day, $format);
			$res['Sunday'] = $day;
		} else {
			$res['Monday'] = self::getBefore(($weekDay - 1)*24*3600, $day, $format);
			$res['Sunday'] = self::getFuture((7 - $weekDay)*24*3600, $day, $format);
		}
	
		return $res;
	}
	
	public function getMonthInfo($day = null, $format = 'Y-m-d')
	{
	    date_default_timezone_set('UTC');
		
		if (!$day) {
            $day = gmdate($format, mktime());
        }  	
	
		$monthDay = date('j',strtotime($day));
		$endDay = date('t',strtotime($day));

		if ($monthDay == 1) {
			$res['Start'] = $day;
			$res['End'] = $endDay;
		} else {
			$res['Start'] = self::getBefore(($monthDay - 1)*24*3600, $day, $format);
			$res['End'] = $endDay;
		}
	
		return $res;
	}   

    /**
     * Get week number of a year
	 *
     *
     * @access public
     * @param string
     * @param int  0 = Sun
     *
     * @return string datetime format
     */
	public static function getWeekNumberInMonth($timestamp, $startWeekDay = 0)
	{
		date_default_timezone_set('UTC');

		$timestampFirstDayOfMonth = strtotime(gmdate('Y-m', $timestamp) . '-01');
		$timestampMonth = gmdate('n', $timestamp);
		$firstDayWeekNumber = gmdate('w', $timestampFirstDayOfMonth);
		
		$weekNumber = 1;

		for ($i=1;$i<7;$i++) {
			$before = $timestamp - 3600 * 24 * 7 * $i;
			$beforeMonth = gmdate('n', $before);
			if ($beforeMonth != $timestampMonth) {
				break;
			}
			$weekNumber++; 
		}
		
		return $weekNumber;
	}

    /**
     * Create a calendar under UTC
	 * setting params:
	 *
     *
     * @access public
     * @param array $setting
     *
     * @return string datetime format
     */
	public static function getCalendar($setting = array())
	{
		//init setting start
		date_default_timezone_set('UTC');
		$defautOptions = array(
			'today' => '',
			'startDay' => '',
			'dayRows' => 31,
			'monthly' => true, //get prev and next months
			'weekStartDay' => 0, // 0 => Sun
			'formatDay' => 'd', // d => 01  j => 1
			'formatWeek' => 'D', // D => Sun  l => Sunday
			'formatMonth' => 'F', // F => January  n  => 1  m => 01 M => Jan
			'formatMonthPer' => 'M',
			'formatDate' => 'm/d/Y',
			'formatYear' => 'Y',
		);

		if($setting){
			foreach($setting as $key => $value) {
				$defautOptions[$key] = $value;
			}
		}
		$setting = $defautOptions;
		//init setting end


		//weekly start day
		if(!$setting['today']){
			//set start day to today
			$setting['today'] = gmdate('Y-m-d', time());
		}
		$timestamp = strtotime($setting['startDay']);
		$timestampToday = strtotime($setting['today']);
		$startDayInWeekNumber = gmdate('w', $timestamp);


		//set new start day
		$timestampBegin = $timestamp; //for complement days for one week
		$timestampStartDay = $timestamp; //record start day timestamp
		$monthDays = gmdate('t', $timestampStartDay); //how many days in a month with startDay
		if($setting['monthly']) {
			$setting['dayRows'] = $monthDays;
		}

		$dayRows = $setting['dayRows'];
		if($startDayInWeekNumber != $setting['weekStartDay']) {
			if($startDayInWeekNumber > $setting['weekStartDay']){
				$dayDiff = $startDayInWeekNumber - $setting['weekStartDay'];
			} else {
				$dayDiff = 7 + $startDayInWeekNumber - $setting['weekStartDay'];
			}
			$timestampBegin = $timestampBegin - $dayDiff * 3600 * 24;
			$dayRows += $dayDiff;
		}
		$weekCount = ceil($dayRows / 7);
		$startDay = gmdate('Y-m-d', $timestampStartDay);
		$endDay = gmdate('Y-m-d', $timestampStartDay + ($setting['dayRows'] - 1) * 86400);

		//put days into weeks
		$weeks = array();
		$timestamp = $timestampBegin;
		$currentMonth = gmdate('Ym', $timestampStartDay);
		$currentMonthStart = $currentMonth . '01';
		$currentMonthEnd = $currentMonth . '31';
		$currentMonthName = '';
		for($i = 0; $i < $weekCount; $i++){
			for($j = 0; $j < 7; $j++){
				$date = gmdate('Ymd', $timestamp);
				
				$weeks[$i][$j] = array(
					'day' => gmdate($setting['formatDay'], $timestamp),
					'dayNumber' => gmdate('j', $timestamp),  // without 0
					'date' => gmdate($setting['formatDate'], $timestamp),
					'datedb' => gmdate('Y-m-d', $timestamp),
					'monthName' => $currentMonthName,
					'isCurrentMonth' => $date >= $currentMonthStart && $date <= $currentMonthEnd ? true : false,
					'isAdd' => false,
				);

				if($weeks[$i][$j]['dayNumber'] == 1){
					$currentMonthName = gmdate($setting['formatMonthPer'], $timestamp);
					$weeks[$i][$j]['monthName'] = $currentMonthName;
				}

				if($weeks[$i][$j]['datedb'] < $startDay || $weeks[$i][$j]['datedb'] > $endDay){
					$weeks[$i][$j]['isAdd'] = true;
				}

				$timestamp += 86400;
			}
		}
		$finishDay = gmdate('Y-m-d', $timestamp - 86400);

		//get week names
		$weekNames = array();
		for($j = 0; $j < 7; $j++){
			$weekNames[] = gmdate($setting['formatWeek'], $timestampBegin + $j * 86400);
		}

		//get month name for startDay
		$monthName =  gmdate($setting['formatMonth'], $timestampStartDay);
		$yearName =  gmdate($setting['formatYear'], $timestampStartDay);


		//get prev & next
		if($setting['monthly']) {
			$currentMonth = gmdate('Y-m-', $timestampStartDay);
			$timestamp = strtotime($currentMonth . '01') - 1;
			$prev = array(
				'startDay' => gmdate('Y-m-', $timestamp) . '01',
				'monthName' => gmdate($setting['formatMonth'], $timestamp),
			);
			$timestamp = strtotime($currentMonth . $monthDays) + 86401;
			$next = array(
				'startDay' => gmdate('Y-m-', $timestamp) . '01',
				'monthName' => gmdate($setting['formatMonth'], $timestamp),
			);
		} else {
			$prev = array(
				'startDay' => gmdate('Y-m-d', $timestampStartDay - $setting['dayRows'] * 86400),
				'monthName' => gmdate($setting['formatMonth'], $timestampStartDay - $setting['dayRows'] * 86400),
			);
			$next = array(
				'startDay' => gmdate('Y-m-d', $timestampStartDay + $setting['dayRows'] * 86400),
				'monthName' => gmdate($setting['formatMonth'], $timestampStartDay + $setting['dayRows'] * 86400),
			);
		}

		//get today
		$timestamp = time();
		return array(
			'yearName' => $yearName,
			'monthName' => $monthName,
			'today' => array(
				'day' => gmdate($setting['formatDay'], $timestampToday),
				'date' => gmdate($setting['formatDate'], $timestampToday),
				'datedb' => gmdate('Y-m-d', $timestampToday),
				'isCurrentMonth' => true,
			),
			'startDay' => $startDay,
			'endDay' => $endDay,
			'beginDay' => gmdate('Y-m-d', $timestampBegin),
			'finishDay' => $finishDay,
			'monthDays' => $monthDays,
			'weekCount' => $weekCount,
			'prev' => $prev,
			'next' => $next,
			'weekNames' => $weekNames,
			'days' => $weeks,
		);
	}

}
